package com.bestcem.xm.user.controller;

import cn.hutool.core.lang.ObjectId;
import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.domain.web.XmResultJson;
import com.bestcem.xm.common.core.enums.ReqErrorCodeEnum;
import com.bestcem.xm.common.core.enums.ResourceErrorCodeEnum;
import com.bestcem.xm.component.security.annotation.XmAuth;
import com.bestcem.xm.component.security.context.SecurityContextHolder;
import com.bestcem.xm.component.security.dto.TokenDTO;
import com.bestcem.xm.user.controller.vo.user.CheckPreferenceVO;
import com.bestcem.xm.user.controller.vo.user.request.CheckPreferenceRequestVO;
import com.bestcem.xm.user.controller.vo.user.request.OrgPassVO;
import com.bestcem.xm.user.controller.vo.user.request.SkinVO;
import com.bestcem.xm.user.controller.vo.user.request.UpdateOrgBaseInfoVO;
import com.bestcem.xm.user.enums.BooleanStatusEnum;
import com.bestcem.xm.user.service.OrganizationService;
import com.bestcem.xm.user.service.UserGroupService;
import com.bestcem.xm.user.service.dto.group.GroupOldAllTreeDTO;
import com.bestcem.xm.user.service.dto.user.CheckPreferenceDTO;
import com.bestcem.xm.user.service.dto.user.OrganizationDTO;
import com.bestcem.xm.user.util.convert.OrganizationConvert;
import com.bestcem.xm.user.util.converter.UserConverter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 公司信息管理服务提供
 *
 * @author qiongyu.cui <qiongyu.cui@idiaoyan.com>
 * @version v1.0
 * @date 2022/3/1 14:41
 */
@RestController
@Slf4j
@RequestMapping(value = "/user")
public class OrganizationController {

    @Resource
    private OrganizationService organizationService;

    @Resource
    private OrganizationConvert organizationConvert;

    @Resource
    private UserGroupService userGroupService;

    /**
     * 修改公司基础信息(公司名称，公司所属行业)
     *
     * @param orgId 公司名字
     * @param vo    需要更新的公司基础信息
     * @return 公司信息
     * @author jishuo.yan <jishuo.yan@idiaoyan.com>
     * @author yun.pan <yun.pan@idiaoyan.com>
     * @date 2022/03/02 15:30
     */
    @PutMapping("/organization/v3/user_org_info/{orgId}")
    public XmResultJson<String> updateOrgInfo(@PathVariable("orgId") String orgId,
                                              @RequestBody UpdateOrgBaseInfoVO vo) {
        // 参数校验
        if (StringUtils.isBlank(orgId)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "url must endswith id");
        }
        if (!ObjectId.isValid(orgId)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_FORMAT, "orgId格式不正确");
        }
        // 获取当前orgId
        String currentOrgId = SecurityContextHolder.getOrgId();
        if (!orgId.equals(currentOrgId)) {
            return XmResultJson.fail(ResourceErrorCodeEnum.PERMISSION_DENY, "Forbidden: no permission");
        }
        // 权限校验
        if (!SecurityContextHolder.getToken().isAdmin()) {
            return XmResultJson.fail(ResourceErrorCodeEnum.PERMISSION_DENY, "only superadmin can do this");
        }
        if (StringUtils.isNotBlank(vo.getIndustryId()) && !ObjectId.isValid(vo.getIndustryId())) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_FORMAT, "industry_id格式不正确!");
        }
        if (StringUtils.isNotBlank(vo.getName())) {
            if (vo.getName().length() > 100) {
                return XmResultJson.fail(ReqErrorCodeEnum.PARAM_RANGE, "param too lang");
            }
            ServiceResult<OrganizationDTO> dtoServiceResult = organizationService.selectByPrimaryKey(orgId);
            if (!dtoServiceResult.isSuccess() || Objects.isNull(dtoServiceResult.getData())) {
                return XmResultJson.fail(ResourceErrorCodeEnum.NOT_FOUND, "org不存在 orgId:" + orgId);
            }
            //OrganizationDTO org = dtoServiceResult.getData();
            //if (!vo.getName().equals(org.getName())) {
            //    organizationMessageSender.orgInfoUpdate(orgId, vo.getName(), org.getCode());
            //}
        }
        // 更新Organization的公司名称和所属行业信息
        ServiceResult<String> result = organizationService.updateUserOrgInfo(orgId, SecurityContextHolder.getUserId(), organizationConvert.voToDto(vo));
        if (result.isSuccess()) {
            return XmResultJson.success(result.getData());
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());
    }

    /**
     * 修改个性化设置(公司皮肤)
     *
     * @param skinVO 皮肤参数
     * @return
     * @author jishuo.yan <jishuo.yan@idiaoyan.com>
     * @author yun.pan <yun.pan@idiaoyan.com>
     * @date 2022/03/02 15:30
     */
    @PutMapping("/organizations/{orgId}/skin/")
    @XmAuth
    public XmResultJson<String> updateOrgSkin(@PathVariable("orgId") String orgId,
                                              @RequestBody SkinVO skinVO) {
        TokenDTO token = SecurityContextHolder.getToken();
        // 参数校验
        if (StringUtils.isBlank(orgId)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "url must endswith id");
        }
        if (!ObjectId.isValid(orgId)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_FORMAT, "orgId格式不正确");
        }

        // name处理
        if (StringUtils.isNotBlank(skinVO.getSystemName())) {
            skinVO.setSystemName(skinVO.getSystemName().trim());
        } else {
            skinVO.setSystemName("");
        }

        // 更新皮肤
        ServiceResult<String> result = organizationService.updateOrgSkin(token, organizationConvert.skinVoToSkinDto(skinVO));
        if (result.isSuccess()) {
            return XmResultJson.success(result.getData());
        } else {
            return XmResultJson.fail(result.getErrorData(), result.getMsg());
        }
    }

    /**
     * 获取投放开关和审核人信息
     * <p>
     * python引用：apps_mysql.user.handlers.OrgDeliverCheckerHandler.get
     * * - “@decorators.render_json”
     *
     * @return com.bestcem.xm.util.XmResultJson<CheckPreferenceVO>
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/03/16 17:28
     */
    @XmAuth
    @GetMapping("/organization/checkpreference/")
    public XmResultJson<CheckPreferenceVO> getChekPreference() {
        // 获取当前用户信息
        TokenDTO currentToken = SecurityContextHolder.getToken();
        ServiceResult<CheckPreferenceDTO> result = organizationService.getCheckPreferenceInfo(currentToken.getOrgId());
        if (result.isSuccess()) {
            CheckPreferenceDTO dto = result.getData();
            CheckPreferenceVO checkPreferenceVO = new CheckPreferenceVO();
            checkPreferenceVO.setCheckUsers(UserConverter.userDtosToUserInfoVos(dto.getCheckUsers()));
            checkPreferenceVO.setCheckDeliver(dto.getCheckDeliver());
            checkPreferenceVO.setCheckSmtpId(dto.getCheckSmtpId());
            return XmResultJson.success(checkPreferenceVO);
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());
    }

    /**
     * 设置投放审核开关和审核人
     * <p>
     * python引用：apps_mysql.user.handlers.OrgDeliverCheckerHandler.post
     * * - “@decorators.render_json“
     * * - “@decorators.permission”
     *
     * @param checkPreferenceVO 审核的相关信息
     * @return com.bestcem.xm.util.XmResultJson<java.lang.Boolean>
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/03/17 10:46
     */
    @PostMapping("/organization/checkpreference/")
    public XmResultJson<Boolean> saveCheckPreference(@RequestBody CheckPreferenceRequestVO checkPreferenceVO) {
        // 获取当前用户信息
        TokenDTO currentToken = SecurityContextHolder.getToken();
        if (Objects.isNull(checkPreferenceVO)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "邮箱配置相关信息不能为空");
        }
        // 处理相关值
        Integer checkDeliver = BooleanStatusEnum.toInteger(checkPreferenceVO.getCheckDeliver());
        String checkSmtpId = Objects.isNull(checkPreferenceVO.getCheckSmtpId()) ? "" : checkPreferenceVO.getCheckSmtpId();
        List<String> userIds = checkPreferenceVO.getCheckUsers();
        ServiceResult<Boolean> result = organizationService.saveCheckPreferenceInfo(currentToken.getOrgId(), checkDeliver,
                checkSmtpId, userIds, currentToken.getUserId());
        if (result.isSuccess()) {
            return XmResultJson.success(result.getData());
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());

    }

    /**
     * 企业中用户修改前端paas配置
     * <p>
     * - python引用：apps_mysql.user.v3.handlers.OrgPaaSInfoHandler
     * * - “@decorators.render_json“
     * * - “@decorators.permission”
     *
     * @param orgId     公司id
     * @param orgPassVO 公司配置信息
     * @return com.bestcem.xm.util.XmResultJson<java.lang.String>
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/05/11 17:31
     */
    @PutMapping("/organization/v3/org_paas_conf/{orgId}")
    public XmResultJson<String> putOrgPassConf(@PathVariable("orgId") String orgId,
                                               @Valid @RequestBody OrgPassVO orgPassVO) {
        TokenDTO currentToken = SecurityContextHolder.getToken();
        String currentOrgId = currentToken.getOrgId();
        if (StringUtils.isBlank(orgId)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "url must endswith id");
        }
        if (!orgId.equals(currentOrgId)) {
            return XmResultJson.fail(ResourceErrorCodeEnum.PERMISSION_DENY, "Forbidden: no permission");
        }
        if (!Boolean.TRUE.equals(BooleanStatusEnum.toBoolean(currentToken.getSuperRole()))) {
            return XmResultJson.fail(ResourceErrorCodeEnum.PERMISSION_DENY, "only superadmin can do this");
        }

        OrganizationDTO organizationDTO = new OrganizationDTO();
        organizationDTO.setOrgId(orgId);
        organizationDTO.setDeliverCheckFlag(BooleanStatusEnum.toInteger(orgPassVO.getDeliverCheck()));
        organizationDTO.setIndustryId(orgPassVO.getIndustryId());
        organizationDTO.setName(orgPassVO.getName());
        if (Objects.nonNull(orgPassVO.getPaasConf())) {
            organizationDTO.setPaasConf(JSON.toJSONString(orgPassVO.getPaasConf()));
        }
        ServiceResult<Boolean> serviceResult = organizationService.updateByPrimaryKeySelective(organizationDTO);
        if (serviceResult.isSuccess()) {
            return XmResultJson.success(orgId);
        }
        return XmResultJson.fail(serviceResult.getErrorData(), serviceResult.getMsg());
    }

    /**
     * 保存公司设置
     *
     * @return com.bestcem.xm.util.XmResultJson<java.lang.String>
     * @author panyun <yun.pan@idiaoyan.com>
     * @date 2022/6/19 16:31
     */
    @PutMapping("/organizations/{orgId}/settings/")
    public XmResultJson<String> saveOrgSetting(@PathVariable("orgId") String orgId,
                                               @RequestBody UpdateOrgBaseInfoVO vo) {
        if (StringUtils.isBlank(orgId)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_LOST, "url must contain orgId");
        }
        if (!ObjectId.isValid(orgId)) {
            return XmResultJson.fail(ReqErrorCodeEnum.PARAM_FORMAT, "orgId格式不正确");
        }

        if (Objects.isNull(vo)) {
            return XmResultJson.success();
        }
        // 更新Organization的公司名称和所属行业信息
        TokenDTO currentToken = SecurityContextHolder.getToken();
        ServiceResult<String> result = organizationService.updateUserOrgInfo(orgId, currentToken.getUserId(), organizationConvert.voToDto(vo));
        if (result.isSuccess()) {
            return XmResultJson.success(result.getData());
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());
    }

    /**
     * 一次性加载所有组织，并拼装成树结构
     */
    @XmAuth
    @GetMapping(value = "/group_tree")
    public XmResultJson<Object> tree() {
        TokenDTO currentToken = SecurityContextHolder.getToken();
        // 分页分层查询
        ServiceResult<GroupOldAllTreeDTO> result = userGroupService.getOldGroupTree(currentToken.getOrgId(), currentToken.getUserId(), currentToken.isAdmin());
        if (result.isSuccess()) {
            return XmResultJson.success(result.getData());
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());
    }

    /**
     * 新增联系人，一次性加载所有组织，并拼装成树结构
     *
     * @return
     */
    @GetMapping("/multi-group-tree")
    public XmResultJson<Object> multiGroupTree() {
        TokenDTO currentToken = SecurityContextHolder.getToken();
        // 分页分层查询
        ServiceResult<GroupOldAllTreeDTO> result = userGroupService.getOldGroupTree(currentToken.getOrgId(), currentToken.getUserId(), currentToken.isAdmin());
        if (result.isSuccess()) {
            JSONObject res = JSON.parseObject(JSON.toJSONString(result.getData()));
            List<JSONObject> tree = new ArrayList<>(1);
            tree.add((JSONObject) res.get("tree"));
            res.put("tree", tree);
            return XmResultJson.success(res);
        }
        return XmResultJson.fail(result.getErrorData(), result.getMsg());
    }
}
